/**
 * Copyright (C) 2012 The SkyTvOS Project
 * <p/>
 * Version     Date           Author
 * ─────────────────────────────────────
 * 2014-7-15         luwei
 */

package com.tianci.appstore.ui.search;

import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.KeyEvent;
import android.view.View;

import com.coocaa.app.gamecenter.framework.ui.GameCenterStatusBar;
import com.coocaa.x.framework.utils.LogUtils;
import com.tianci.appstore.controller.AppStoreSearchController;
import com.tianci.appstore.ui.control.SkyMainPageController.OnPageChangeListener;
import com.tianci.appstore.ui.data.SkyAppBaseData;
import com.tianci.appstore.ui.data.SkyAppDetailData;
import com.tianci.appstore.ui.data.SkyListAppData;
import com.tianci.appstore.ui.list.ListFlipper;
import com.tianci.appstore.ui.list.SkyListAdapter;
import com.tianci.appstore.ui.list.cgylist.ListOperationController;
import com.tianci.appstore.ui.search.SearchInputLayout.ClearFocusListener;
import com.tianci.appstore.ui.widget.SkyBaseItemView;
import com.tianci.appstore.ui.widget.SkyCustomLayout;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

public class SearchController extends ListOperationController implements OnSearchKeyChangeListener,
        SearchDataListener, ClearFocusListener {
    private OnPageChangeListener mPageChangeListener = null;
    public static String mSearchKey = "";
    private SkyCustomLayout mHotLayout = null;
    private SearchListView mContentLayout = null;
    private List<SkyListAppData> mHotListAppDatas = new ArrayList<SkyListAppData>();
    private int mLastFocus = 0;
    private boolean mIsFirst = true;
    private String mLogKey = "";
    private SearchResultListener mSearchResultListener = null;
    private int mCount = 0;
    private boolean isGame = false;
    private GameCenterStatusBar mStatusBar = null;

    public SearchController(Context context, ListFlipper flipper, int row, int column) {
        super(context, flipper, row, column);
    }

    public void setStatusBar(GameCenterStatusBar statusBar) {
        this.mStatusBar = statusBar;
    }

    public void setSearchResultListener(SearchResultListener listener) {
        this.mSearchResultListener = listener;
    }

    public void setPageChangeListener(OnPageChangeListener listener) {
        this.mPageChangeListener = listener;
    }

    public void setGame(boolean game) {
        this.isGame = game;
    }

    public void setHotLayout(SkyCustomLayout layout) {
        this.mHotLayout = layout;
        AppStoreSearchController.getAppStoreSearchController().getSearchRanking(isGame);
        mContentLayout.setLoadingVisible(true);
    }

    public void setContentLayout(SearchListView layout) {
        this.mContentLayout = layout;
        mHandler.sendEmptyMessageDelayed(DELAY_INIT_ITEM, 500);
    }

    @Override
    public boolean onKeyDown(int keyCode, int index, boolean[] turnPage) {
        mLastFocus = index;
        if (turnPage[1] && keyCode == KeyEvent.KEYCODE_DPAD_UP) {
            if (mCurrentPage > 0) {
                LogUtils.d("the current page is " + mCurrentPage + " and turn pre");
                direction = keyCode;
                mPager.setFocusable(true);
                mPager.setFocusableInTouchMode(true);
                mPager.requestFocus();
                int oldIndex = mPager.getDisplayedChild();
                mPager.displayPrePage();
                if (mStatusBar != null) {
                    mStatusBar.movePre();
                }
                mCurrentPage--;
                posY = index / row;
                if (mPageChangeListener != null) {
                    mPageChangeListener.onPageChange(mCurrentPage + 1, mTotalPage);
                }
                if (mCurrentPage > 0 && mCurrentPage < mTotalPage - 1) {
                    int lastIndex = (oldIndex + 1) % ListFlipper.VIEW_PAGE_COUNT;
                    SkyCustomLayout lastLayout = (SkyCustomLayout) mPager.getChildAt(lastIndex);
                    SkyListAdapter adapter = (SkyListAdapter) lastLayout.getAdapter();
                    adapter.clearData(mCurrentPage - 1, pageSize);
                }
                requestUnloadData();
                return true;
            }
//            else
//                mPager.hitBoundary(keyCode);
        } else if (turnPage[3] && keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
            if (mCurrentPage < mTotalPage - 1) {
                LogUtils.d("the current page is " + mCurrentPage + " and turn next");
                direction = keyCode;
                mPager.setFocusable(true);
                mPager.setFocusableInTouchMode(true);
                mPager.requestFocus();
                int oldIndex = mPager.getDisplayedChild();
                mPager.displayNextPage();
                if (mStatusBar != null) {
                    mStatusBar.moveNext();
                }
                mCurrentPage++;
                posY = index / row;
                if (mPageChangeListener != null) {
                    mPageChangeListener.onPageChange(mCurrentPage + 1, mTotalPage);
                }

                if (mCurrentPage > 0 && mCurrentPage < mTotalPage - 1) {
                    int firstIndex = (oldIndex + ListFlipper.VIEW_PAGE_COUNT - 1) % ListFlipper.VIEW_PAGE_COUNT;
                    SkyCustomLayout firstLayout = (SkyCustomLayout) mPager.getChildAt(firstIndex);
                    SkyListAdapter adapter = (SkyListAdapter) firstLayout.getAdapter();
                    adapter.clearData(mCurrentPage + 1, getCountByIndex(mCurrentPage + 1));
                }
                requestUnloadData();
                return true;
            }
//            else
//                mPager.hitBoundary(keyCode);
        } else if (!turnPage[3] && keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
            if (mPager.getVisibility() == View.VISIBLE) {
                SkyCustomLayout layout = (SkyCustomLayout) mPager.getChildAt(mPager.getDisplayedChild());
                if ((layout.getChildCount() % 2 == 0 && index >= layout.getChildCount() - 2)
                        || (layout.getChildCount() % 2 == 1 && index >= layout.getChildCount() - 1)) {
                    return true;
                }
            } else if (mHotLayout.getVisibility() == View.VISIBLE) {
                if (index == mHotLayout.getChildCount() - 1) {
                    return true;
                }
            }

        }
        return false;
    }

    private void requestUnloadData() {
        SkyCustomLayout child;
        SkyListAdapter adapter;
        for (int i = 0; i < mPager.getChildCount(); i++) {
            child = (SkyCustomLayout) mPager.getChildAt(i);
            adapter = (SkyListAdapter) child.getAdapter();
            if (!adapter.isDataFilled()) {
                int index = adapter.getPageIndex();
                if (index >= 0 && index < mTotalPage)
                    AppStoreSearchController.getAppStoreSearchController().getSearchList(mSearchKey, index + 1, pageSize, isGame);
            }
        }
    }

    @Override
    public boolean onAnimEnd(int current) {
        SkyBaseItemView.mKey = true;
        mPager.setFocusable(false);
        mPager.setFocusableInTouchMode(false);
        mPager.clearFocus();
        if (direction == KeyEvent.KEYCODE_DPAD_DOWN) {
            SkyCustomLayout layer = (SkyCustomLayout) mPager.getChildAt(mPager.getDisplayedChild());
            if (mLastFocus == 6) {
                layer.setFocusPos(0, true);
            } else if (mLastFocus == 7) {
                if (layer.getChildCount() > 1) {
                    layer.setFocusPos(1, true);
                } else {
                    layer.setFocusPos(0, true);
                }
            }
        } else if (direction == KeyEvent.KEYCODE_DPAD_UP) {
            SkyCustomLayout layer = (SkyCustomLayout) mPager.getChildAt(mPager.getDisplayedChild());
            if (mLastFocus == 0) {
                layer.setFocusPos(6, true);
            } else if (mLastFocus == 1) {
                layer.setFocusPos(7, true);
            }
        }
        if (dataCan.size() > 0) {
            Iterator iter = dataCan.entrySet().iterator();
            while (iter.hasNext()) {
                Entry entry = (Entry) iter.next();
                int key = (Integer) entry.getKey();
                List<SkyListAppData> value = (List<SkyListAppData>) entry.getValue();
                refreshPage(key, value);
            }
            dataCan.clear();
        }
        return false;
    }

    private void requestUnloadDataFirst() {
        SkyCustomLayout child;
        SkyListAdapter adapter;
        mPager.setDisplayedChild(0);
        child = (SkyCustomLayout) mPager.getChildAt(0);
        adapter = (SkyListAdapter) child.getAdapter();
        adapter.refreshUI(new ArrayList<SkyAppBaseData>());
        AppStoreSearchController.getAppStoreSearchController().getSearchList(mSearchKey, 1,
                pageSize, isGame);
        mContentLayout.setLoadingVisible(true);
        LogUtils.d("the search key is " + mSearchKey + " to first search ");

    }

    public void initNewKey(int count, int pageIndex) {
        initAppCount(count, pageIndex);

        int index = pageIndex - 1;
        int displayChild = 1;
        if (index < 0) {
            index = 0;
            displayChild = 0;
        } else if (index >= mTotalPage - 2) {
            index = pageIndex - 2;
            displayChild = 2;
        }
        for (int i = 0; i < ListFlipper.VIEW_PAGE_COUNT && i < mTotalPage; i++) {
            SkyCustomLayout child = (SkyCustomLayout) mPager.getChildAt(i);
            SkyListAdapter adapter = (SkyListAdapter) child.getAdapter();
            adapter.clearData(index + i, getCountByIndex(index + i));
        }
        mPager.setInAnimation(null);
        mPager.setOutAnimation(null);
        mPager.setDisplayedChild(displayChild);
    }

    protected void initAppCount(int totalCount, int pageIndex) {
        this.totalCount = totalCount;
        this.mTotalPage = totalCount / (row * column);
        if (totalCount % (row * column) != 0)
            this.mTotalPage++;
        if (pageIndex < 0 || pageIndex >= mTotalPage)
            pageIndex = 0;
        this.mCurrentPage = pageIndex;
        if (mPageChangeListener != null) {
            mPageChangeListener.onPageChange(1, mTotalPage);
        }
        LogUtils.d("the search key " + mSearchKey + " totalpage = " + mTotalPage);
        if (mStatusBar != null) {
            mStatusBar.initProgressbar(mTotalPage);
        }
    }

    @Override
    public void searchKeyChange(String key) {
        mSearchKey = key;
        if (mSearchKey.equals("")) {
            mHandler.sendEmptyMessage(REFRESH_HOT_LAYOUT);
        } else {
            mIsFirst = true;
            requestUnloadDataFirst();
        }
    }

    public static final int REFRESH_PAGE = 0;
    public static final int REFRESH_HOT_LAYOUT = 1;
    public static final int REFRESH_NO_SEARCH = 2;
    public static final int DELAY_INIT_ITEM = 3;
    public static final int SET_FOCUS_MSG = 4;
    public static final int REFRESH_INSTALL_STATUE = 5;
    Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            mContentLayout.setLoadingVisible(false);
            switch (msg.what) {
                case REFRESH_PAGE:
                    mContentLayout.showHotLayout(false);
                    mContentLayout.showSearchResultText(mSearchKey, msg.arg2);
                    if (msg.arg1 == 1 && mIsFirst) {
                        mIsFirst = false;
                        initNewKey(msg.arg2, 0);
                        if (mTotalPage > 1)
                            AppStoreSearchController.getAppStoreSearchController().getSearchList(mSearchKey, 2, pageSize, isGame);
                    }
                    refreshPage(msg.arg1 - 1, (List<SkyListAppData>) msg.obj);
                    break;
                case REFRESH_HOT_LAYOUT:
                    mContentLayout.showHotLayout(true);
                    mContentLayout.searchHotResult();
                    if (isGame) {
                        List<SkyAppBaseData> skyAppBaseDataList = new ArrayList<SkyAppBaseData>();
                        skyAppBaseDataList.addAll(mHotListAppDatas);
                        mHotLayout.getAdapter().refreshUI(
                                skyAppBaseDataList.size() > 8 ? skyAppBaseDataList.subList(0, 8)
                                        : skyAppBaseDataList);
                    } else {
                        SkyListAdapter hotAdapter = (SkyListAdapter) mHotLayout.getAdapter();
                        hotAdapter.setData(0, mHotListAppDatas.size() > 8 ? mHotListAppDatas.subList(0, 8)
                                : mHotListAppDatas);
                    }
                    break;
                case REFRESH_NO_SEARCH:
                    if (mHotListAppDatas.size() > 0) {
                        mContentLayout.showHotLayout(true);
                        mContentLayout.searchNoResult();
                        if (isGame) {
                            List<SkyAppBaseData> appDatas = new ArrayList<SkyAppBaseData>();
                            appDatas.addAll(getRandHotAppDatas());
                            mHotLayout.getAdapter().refreshUI(appDatas);
                        } else {
                            SkyListAdapter hotAdapter = (SkyListAdapter) mHotLayout.getAdapter();
                            hotAdapter.setData(0, getRandHotAppDatas());
                        }
                    }
                    break;
                case DELAY_INIT_ITEM:
                    for (int i = 0; i < ListFlipper.VIEW_PAGE_COUNT; i++) {
                        LogUtils.d("delay init page item " + i);
                        SkyCustomLayout child = (SkyCustomLayout) mPager.getChildAt(i);
                        SkyListAdapter adapter = (SkyListAdapter) child.getAdapter();
                        adapter.clearData(i, 8);
                    }
                    break;
                case SET_FOCUS_MSG:

                    break;
                case REFRESH_INSTALL_STATUE:
                    Bundle bundle = msg.getData();
                    String pkg = bundle.getString("pkg");
                    boolean isInstall = bundle.getBoolean("isInstall");
                    refreshStatue(pkg, isInstall);
                    break;
                default:
                    break;
            }
        }

        ;
    };

    private List<SkyListAppData> getRandHotAppDatas() {
        List<SkyListAppData> appDatas = new ArrayList<SkyListAppData>();
        int count = 5;
        if (!isGame)
            count = 4;
        if (mHotListAppDatas.size() > count) {
            int[] rand = randomCommon(0, mHotListAppDatas.size(), count);
            for (int i = 0; i < count; i++) {
                appDatas.add(mHotListAppDatas.get(rand[i]));
            }
        } else {
            appDatas.addAll(mHotListAppDatas);
        }
        return appDatas;
    }

    public static int[] randomCommon(int min, int max, int n) {
        if (n > (max - min + 1) || max < min) {
            return null;
        }
        int[] result = new int[n];
        int count = 0;
        while (count < n) {
            int num = (int) (Math.random() * (max - min)) + min;
            boolean flag = true;
            for (int j = 0; j < n; j++) {
                if (num == result[j]) {
                    flag = false;
                    break;
                }
            }
            if (flag) {
                result[count] = num;
                count++;
            }
        }
        return result;
    }

    @Override
    public void onAppPageLoaded(String key, int pageIndex, int count, List<SkyListAppData> appList) {
        if (key.equals(mSearchKey)) {
            mCount = count;
            if (appList != null && appList.size() > 0) {
                LogUtils.d("the search key is " + key + " and the size is " + appList.size());
                Message msg = mHandler.obtainMessage(REFRESH_PAGE);
                msg.arg1 = pageIndex;
                msg.arg2 = count;
                msg.obj = appList;
                mHandler.sendMessage(msg);
            } else {
                mHandler.sendEmptyMessage(REFRESH_NO_SEARCH);
            }
            if (mSearchResultListener != null) {
                mSearchResultListener.onSearchResult(key, count);
            }
        }
    }

    @Override
    public void onHotAppLoaded(List<SkyListAppData> appList) {
        if (appList != null) {
            mHotListAppDatas.clear();
            mHotListAppDatas.addAll(appList);
        }
        mHandler.sendEmptyMessage(REFRESH_HOT_LAYOUT);
    }

    private void refreshStatue(String pkg, boolean isInstall) {
        SkyCustomLayout child;
        List<View> mChildViews;
        int i = 0;

        if (mHotLayout != null) {
            mChildViews = mHotLayout.getChildViews();
            if (mChildViews != null && mChildViews.size() != 0) {
                for (i = 0; i < mChildViews.size(); i++) {
                    View view = mChildViews.get(i);
                    if (view instanceof SearchListBlock) {
                        SearchListBlock searchListBlock = (SearchListBlock) view;
                        if (searchListBlock != null && pkg != null && pkg.equals(searchListBlock.pkgName)) {
                            if (isInstall)
                                searchListBlock.addInstallTag();
                            else
                                searchListBlock.removeInstallTag();
                            break;
                        }
                    }
                }
            }
        }

        if (pkg == null || mPager == null || mPager.getChildCount() == 0)
            return;
        for (i = 0; i < mPager.getChildCount(); i++) {
            child = (SkyCustomLayout) mPager.getChildAt(i);
            mChildViews = child.getChildViews();
            if (mChildViews != null && mChildViews.size() > 0) {
                for (View view : mChildViews) {
                    if (view instanceof SearchListBlock) {
                        SearchListBlock searchListBlock = (SearchListBlock) view;
                        if (searchListBlock != null && pkg != null && pkg.equals(searchListBlock.pkgName)) {
                            LogUtils.i("searchController", "pkg.equals(searchListBlock.pkgName) isInstall: " + isInstall);
                            if (isInstall)
                                searchListBlock.addInstallTag();
                            else
                                searchListBlock.removeInstallTag();
                            break;
                        }
                    }
                }
            }
        }
    }

    @Override
    public void onRefreshAppStatus(String pkg, SkyAppDetailData.AppStatus status) {

        LogUtils.i("searchController", "onRefreshAppStatus pkg: " + pkg + ",status:  " + status);
        Message msg = mHandler.obtainMessage(REFRESH_INSTALL_STATUE);
        Bundle bundle = new Bundle();
        if (status == SkyAppDetailData.AppStatus.INSTALLED) {
            bundle.putString("pkg", pkg);
            bundle.putBoolean("isInstall", true);
            msg.setData(bundle);
            mHandler.sendMessage(msg);
        } else if (status == SkyAppDetailData.AppStatus.NOT_DOWNLOADED) {
            bundle.putString("pkg", pkg);
            bundle.putBoolean("isInstall", false);
            msg.setData(bundle);
            mHandler.sendMessage(msg);
        }
    }

    @Override
    public boolean clearFocus(int keyCode) {
        if (mPager.getVisibility() == View.VISIBLE) {
            SkyCustomLayout layout = (SkyCustomLayout) mPager.getChildAt(mPager.getDisplayedChild());
            layout.setFocusPos(0, true);
        } else {
            if (mHotLayout.getChildCount() > 0) {
                mHotLayout.setFocusPos(0, true);
            }
        }
        submitSearchKey();
        return true;
    }

    private void submitSearchKey() {
        if (!mSearchKey.equals("") && !mSearchKey.equals(mLogKey)) {
            mLogKey = mSearchKey;
        }
    }

    @Override
    protected HashMap<String, String[]> addItemCommand(HashMap<String, String[]> old) {
        if (mHotLayout.getVisibility() == View.VISIBLE) {
            return ((SkyListAdapter) mHotLayout.getAdapter()).getAppListNames(old);
        } else {
            return super.addItemCommand(old);
        }
    }

    @Override
    protected SkyCustomLayout getCurrentPage() {
        if (mHotLayout.getVisibility() == View.VISIBLE) {
            return mHotLayout;
        }
        return super.getCurrentPage();
    }

    @Override
    public String getScene() {
        // TODO Auto-generated method stub
        return "com.tianci.appstore:SearchActivity";
    }
}
